home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 011 / autotest.cq / autotest.c
Encoding:
C/C++ Source or Header  |  1985-05-26  |  8.0 KB  |  321 lines

  1. /* Autotest.C - Test raw disk I/O - Nov. 84 PC Tech Journal pp 64-70 */
  2. /*              Modified for DeSmet C - H.G.Williams                 */
  3.  
  4. #include "stdio.h"
  5.  
  6. #define ASIZE 25000                   /* size of buffer area   */
  7.  
  8. long seqio() , randio() ;
  9. long gettime() ;
  10. char *align() ;
  11. int dno , nstart , i ,nit ;
  12. char *pbuf ;
  13.  
  14. int clu , cfree , tot , bps ;         /* disk space variables */
  15. long totsec ;                         /* total sectors        */
  16.  
  17. main(argc,argv)
  18. int argc ;
  19. char *argv ;
  20. {
  21.    char area[ASIZE] ;
  22.  
  23.    /* ensure that buffer does not cross a 64K address boundry */
  24.  
  25.    pbuf = align(area,ASIZE/2) ;
  26.  
  27.    printf("\n Drive No. (0 = A , 1 = B , ...): ") ;
  28.    scanf("%d" , &dno) ;
  29.  
  30.    clu = getspac(dno+1 , &cfree , &tot , &bps) ;
  31.    if (clu == 0xffff)
  32.    {
  33.       printf("\n Invalid Drive Number \n") ;
  34.       exit(10) ;
  35.    }
  36.  
  37.    totsec = clu * (long) tot ;
  38.    printf("\n Total Number Of Sectors = %1u \n" , totsec) ;
  39.  
  40.    nstart = 0 ; 
  41.    nit = 20 ;
  42.    printf("\n Sequential Reads \n") ;
  43.    doseg( 1) ;                        /* sequential read tests */
  44.    doseg( 8) ;
  45.    doseg(16) ;
  46.    doseg(24) ;
  47.  
  48.    nit = 40 ;
  49.    printf("\n Random Reads - %2d Sector \n" , 1) ;
  50.    dorand(1 , 0.10) ;
  51.    dorand(1 , 0.33) ;                 /* random read tests */
  52.    dorand(1 , 0.50) ;
  53.    dorand(1 , 0.90) ;
  54.  
  55.    nit = 20 ;
  56.    printf("\n Random Reads = %2d Sector \n" , 8) ;
  57.    dorand(8 , 0.10) ;
  58.    dorand(8 , 0.33) ;
  59.    dorand(8 , 0.50) ;
  60.    dorand(8 , 0.90) ;
  61.  
  62. }
  63.  
  64. int doseg(nseg)
  65. int nseg ;
  66. {
  67.    long t ;
  68.  
  69.    t = seqio(dno,nseg,nstart,pbuf,nit) ;
  70.    printf(" %2d Sectors          - " , nseg) ;
  71.    printf("  %4.3f Sec/Read \n" , t/(18.2*nit)) ;
  72. }
  73.  
  74. int dorand(nseg,frac)
  75. int nseg ;
  76. float frac ;
  77. {
  78.    long t ;
  79.    int offset ;
  80.  
  81.    offset = totsec * frac ;
  82.    t = randio(dno,nseg,nstart,pbuf,nit,offset) ;
  83.    printf(" %5.2f Width Seeks   - " , frac) ;
  84.    printf("  %4.3f Sec/Read \n" , t/(18.2*nit)) ;
  85. }
  86.  
  87. /* seqio.c - do a sequential io test */
  88.  
  89. long seqio(dno,nseg,nstart,buffer,nit)
  90.   int dno , nstart , nseg , nit ;
  91.   char *buffer ;
  92. {
  93.    int i , nerror ;
  94.    long t ;
  95.  
  96.    nerror = 0 ;
  97.  
  98.    /* do one read to fix starting point */
  99.  
  100.    if(rawread(dno,1,nstart,buffer) != 0)
  101.       nerror = nerror + 1 ;
  102.  
  103.    /* now do a series of reads */
  104.  
  105.    t = gettime() ;                    /* start timing */
  106.    for(i=0 ; i<nit ; i=i+1)
  107.    {                                  /* read and check for errors */
  108.       if(rawread(dno,nseg,nstart,buffer) != 0)
  109.          nerror = nerror + 1 ;
  110.       nstart = nstart + nseg ;        /* move past area read */
  111.    }
  112.  
  113.    t = gettime() - t ;                /* get elapsed time */
  114.    if(t <= 0L)
  115.       t = t+0x1800B0 ;
  116.  
  117.    if(nerror > 0)
  118.       printf(" %d errors \n" , nerror) ;
  119.  
  120.    return(t) ;                        /* return elapsed time in ticks */
  121. }
  122.  
  123. /* randio.c - test random raw disk i/o */
  124.  
  125. long randio(dno,nseg,nstart,buffer,nit,offset)
  126.   int dno , nstart , nseg , nit ;
  127.   char *buffer ;
  128.   int offset ;
  129. {
  130.    int i , nerror ;
  131.    long t ;
  132.  
  133.    nerror = 0 ;
  134.                                       /* do a read in second area to start */
  135.  
  136.    if(rawread(dno,nseg,nstart+offset,buffer) != 0)
  137.       nerror = nerror + 1 ;
  138.  
  139.    t = gettime() ;                    /* start timing */
  140.  
  141.    for(i=0 ; i < (nit/2) ; i=i+1)
  142.    {                                  /* read first area */
  143.       if(rawread(dno,nseg,nstart,buffer) != 0)
  144.          nerror = nerror + 1 ;
  145.                                       /* read second area */
  146.       if(rawread(dno,nseg,nstart+offset,buffer) != 0)
  147.          nerror = nerror + 1 ;
  148.       nstart = nstart + nseg ;
  149.    }
  150.  
  151.    t = gettime() - t ;
  152.    if(t < 0L)
  153.       t = t + 0x1800B0 ;
  154.  
  155.    if(nerror > 0)
  156.       printf(" %d errors \n" , nerror) ;
  157.  
  158.    return(t) ;
  159. }
  160.  
  161. /* align.c - align a buffer so that it does not cross a 64K boundry */
  162. /* Given the address of a buffer area it returns a starting address */
  163. /* such that the following (size) bytes do not cross a 64K byte     */
  164. /* address boundry.                                                 */
  165.  
  166. unsigned get_ds() ;
  167.  
  168. char *align(area,size)                /* align buffer address */
  169.   char *area ;                        /* start of buffer area */
  170.   int size ;                          /* size required for buffer */
  171.  
  172. {
  173.    long begin ;                       /* flat address for area */
  174.    unsigned room ;                    /* number of bytes to boundry */
  175.  
  176.    /* build flat address */
  177.  
  178.    begin = ((long) get_ds()) * 16L + (long) area ;
  179.  
  180.    /* get distance to boundry */
  181.  
  182.    room = 0x10000 - (begin & 0xffff) ;
  183.    if (room >= size)
  184.       return(area) ;
  185.    else return(area+room) ;
  186. }
  187.  
  188. dummy()
  189. {
  190. #asm
  191.  
  192. ; assembler functions for disk i/o performance benchmark
  193. ;
  194. ; rawread(drive,nsec,begin_sec,buffer) - reads raw disk sectors
  195. ;    drive     = drive number  0=A , 1=B , .....
  196. ;    nsec      = number of 512 byte sectors to read
  197. ;    begin_sec = number of first logical sector to read
  198. ;    buffer    = store the data here (relative to ds)
  199.  
  200. cseg
  201. public rawread,rawread_,_rawread
  202.  
  203. ; define the argument offsets relative to BP
  204. ; old BP value is at zero
  205. ; return address is at 2
  206.                    
  207. drive     equ 4
  208. nsec      equ 6
  209. begsec    equ 8
  210. buffer    equ 10
  211.          
  212. rawread:
  213. rawread_:
  214. _rawread: push bp
  215.           mov bp,sp
  216.           push bx
  217.           push cx
  218.           push dx
  219.           push si
  220.           push di
  221.           mov ax,word [bp+drive]
  222.           mov cx,word [bp+nsec]
  223.           mov dx,word [bp+begsec]
  224.           mov bx,word [bp+buffer]
  225.           int 25H                  ; absolute disk read
  226.           pop cx                   ; discard original flags
  227.           pop di
  228.           pop si
  229.           pop dx
  230.           pop cx
  231.           pop bx
  232.           jc raw1                  ; did the operation succeed ?
  233.           mov ax,0                 ;   yes - set ax to 0
  234.           jmp raw2
  235. raw1:                              ;   no  - force ax to be non-zero
  236.           or ax,ax                 ; is ax already non-zero ?
  237.           jnz raw2                 ;   yes - just use it as an error return
  238.           mov ax,255               ;   no  - fake a non-zero error return
  239. raw2:
  240.           pop bp
  241.           ret
  242.  
  243. ; get_ds() - returns the data segment register
  244.           
  245. public get_ds,get_ds_,_get_ds
  246.           
  247. get_ds:
  248. get_ds_:
  249. _get_ds:
  250.           mov ax,ds
  251.           ret
  252.  
  253. ; long gettime() - returns time
  254.           
  255. public gettime,gettime_,_gettime
  256.           
  257. gettime:
  258. gettime_:
  259. _gettime:
  260.           push cx
  261.           push dx
  262.           mov ax,0                 ; read clock function
  263.           int 1AH                  ; time-of-day BIOS call
  264.  
  265. ; set up long return (dx high, ax low)
  266.  
  267.           mov ax,dx
  268.           mov dx,cx
  269.           pop dx
  270.           pop cx
  271.           ret
  272.  
  273. ; getspac(ddrive,pfree,ptot,pbytes) - get disk free space info
  274. ;    ddrive = drive number  0=A , 1=B .......
  275. ;    pfree  = number of free clusters
  276. ;    ptot   = total number of clusters
  277. ;    pbytes = number of bytes per sector
  278. ;    returns number of sectors per cluster - 0xFFFF for invalid drive
  279.  
  280. ; define argument offsets
  281. ; old BP = 0
  282. ; return address = 2
  283.  
  284. ddrive    equ 4
  285. pfree     equ 6
  286. ptot      equ 8
  287. pbytes    equ 10
  288.           
  289. public getspac,getspac_,_getspac
  290.           
  291. getspac:
  292. getspac_:
  293. _getspac:
  294.           push bp
  295.           mov bp,sp
  296.           push bx
  297.           push cx
  298.           push dx
  299.           push si
  300.           mov dx,word [bp+ddrive]
  301.           mov ah,36H               ; DOS get free space call
  302.           int 21H
  303.           mov si,word [bp+pfree]   ; free clusters
  304.           mov word [si],bx
  305.           mov si,word [bp+ptot]    ; total clusters
  306.           mov word [si],dx
  307.           mov si,word [bp+pbytes]  ; bytes per sector
  308.           mov word [si],cx
  309.           ; sectors per cluster already in ax
  310.  
  311. ; restore registers
  312.  
  313.           pop si
  314.           pop dx
  315.           pop cx
  316.           pop dx
  317.           pop bp
  318.           ret
  319. #
  320. }